<template>
  <div class="main-container">
    <div class="Block mc-left">
      <div class="BlockTitle"><h3>模型结构树</h3></div>
      <div class="BlockBody">
        <div class="tree-content">
          <a-tree
            :tree-data="treeData"
            :replaceFields="replaceFields"
            :selectedKeys="selectedKeys"
            :expandedKeys="expandedKeys"
            @select="selectNode"
            @expand="expandNode"
            ref="tree"
          >
          </a-tree>
        </div>
      </div>
    </div>
    <div class="mc-right" v-show="attrDatas.length > 0">
      <div class="title">{{ selectedTitle }}</div>
      <div class="body">
        <div class="attr-content">
          <p
            v-for="attr in attrDatas"
            :key="attr.id"
            class="attr-row"
            :class="attr.type === attrType.img ? 'image-row' : ''"
          >
            <span class="name">{{ attr.name }} </span>
            :
            <a
              class="content file"
              v-if="attr.type === attrType.file"
              :href="attr.bimValue"
              target="_blank"
              >相关文件</a
            >
            <viewer v-else-if="attr.type === attrType.img" class="content">
              <img :src="attr.bimValue" class="image" />
            </viewer>
            <span class="content" v-else>{{ attr.bimValue }}</span>
          </p>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
// import { getAction, deleteAction } from "@api/manage";
import modeldatas from "@/datas/model.json";
export default {
  name: "home",
  data() {
    return {
      treeData: [],
      replaceFields: { children: "child", title: "name", key: "id" },
      selectNodes: [],
      // 选中节点
      selectedKeys: [],
      //当前选中节点的节点名称
      selectedTitle: "",
      //当前选中节点的节点属性
      attrDatas: [],
      // 展开节点
      expandedKeys: [],
      // 选中节点及子阶段ue4Id
      selectUe4ids: [],
      // 属性类型
      attrType: {
        img: "图片",
        file: "文件",
        text: "文本",
      },
      url: {
        list: "/bim/bimStructureInfo/getTreeList",
      },
    };
  },
  methods: {
    //页面的默认加载事件
    initPage() {
      setTimeout(() => {
        if (this.ue4Viewer && Object.keys(this.ue4Viewer).length != 0) {
          this.ue4Viewer.setSelectedNodeByue4Id(this.selectedNodeByue4Id);
        }
      });
    },
    //树==============================================================================
    // 树结构节点点击触发
    selectNodeHeightLight(selectUe4ids) {
      // 去除高亮
      this.ue4Viewer.unhighlightAll();
      this.selectNodes = selectUe4ids || [];
      this.ue4Viewer.highlight(this.selectNodes);
    },

    expandNode(keys) {
      this.expandedKeys = [];
      this.expandedKeys = keys;
    },
    // 树结构节点选中事件
    selectNode(val) {
      this.selectedKeys = val;
      if (!val || val.length == 0) {
        // 取消节点选中
        // this.$emit('select', this.selectKeys)
        this.selectNodeHeightLight(this.selectUe4ids);
        return;
      }
      let node = this.getNodeById(this.treeData, val[0]);
      if (!node || !node.id) {
        return this.$message.error("未找到选中节点!");
      }
      //设置节点标题和属性
      this.selectedTitle = node.name;
      this.attrDatas = node.sub || [];

      this.selectUe4ids = this.getNodeUe4Id([node]);
      // 高亮ue4Id
      this.selectNodeHeightLight(this.selectUe4ids);
      // 飞入模型位置
      if (this.selectedKeys.length > 0)
        this.ue4Viewer.flyto(node, {
          id: this.selectUe4ids[0],
          distance: 5000,
        });
      else this.ue4Viewer.flyto(node, { distance: 5000 });
    },

    // 返回节点所有子节点ue4Id
    getNodeUe4Id(nodes) {
      let list = [];
      for (let i in nodes) {
        let node = nodes[i];
        if (node.ue4Id) list.push(node.ue4Id);
        // 存在节点
        if (node.child && node.child.length > 0) {
          let childList = this.getNodeUe4Id(node.child);
          if (childList && childList.length > 0) {
            childList.forEach((element) => {
              list.push(element);
            });
          }
        }
      }
      return list;
    },

    // 根据ue4Id选中树节点
    selectedNodeByue4Id(ue4Id) {
      // 查询id
      let node = this.getIdByUe4Id(this.treeData, ue4Id);
      if (node && node.id) {
        // 选中
        this.selectedKeys = [];
        this.selectedKeys.push(node.id);
        // 展开指定节点
        this.expandedKeys = [];
        let ids = node.path.split("@");
        for (let i in ids) {
          if (ids[i] && ids[i] != "") this.expandedKeys.push(ids[i]);
        }
      }
      return node;
    },

    // 根据ue4Id查询节点
    // treeData  数据源
    getIdByUe4Id(treeData, ue4Id) {
      let currentNode = {};
      for (let i in treeData) {
        let node = treeData[i];
        if (node.ue4Id == ue4Id) currentNode = node;
        // 找到节点，直接返回
        if (currentNode && currentNode.id) return currentNode;
        // 存在节点
        if (node.child && node.child.length > 0) {
          //递归
          let childNode = this.getIdByUe4Id(node.child, ue4Id);
          if (childNode && childNode.id) {
            currentNode = childNode;
            return currentNode;
          }
        }
      }
    },

    // 根据节点id返回节点对象
    getNodeById(treeData, id) {
      let currentNode = {};
      for (let i in treeData) {
        let node = treeData[i];
        if (node.id == id) {
          currentNode = node;
        }
        // 找到节点，直接返回
        if (currentNode && currentNode.id) return currentNode;
        // 存在节点
        if (node.child && node.child.length > 0) {
          let childNode = this.getNodeById(node.child, id);
          if (childNode && childNode.id) {
            currentNode = childNode;
            return currentNode;
          }
        }
      }
    },
    // 请求树节点信息
    loadData() {
      this.loading = true;
      let params = {};

      let res = modeldatas;
      if (res.success) {
        this.treeData = res.result;
      } else {
        this.$message.warning(res.message);
      }
      // return
      // getAction(this.url.list, params)
      //   .then((res) => {
      //     if (res.success) {
      //       this.treeData = res.result;
      //       console.log("树结构数据：", this.treeData);
      //     } else {
      //       this.$message.warning(res.message);
      //     }
      //   })
      //   .finally(() => {
      //     this.loading = false;
      //   });
    },
  },
  created() {
    this.loadData();
  },
  mounted() {
    // if (this.ue4Viewer && Object.keys(this.ue4Viewer).length != 0) {
    //   this.ue4Viewer.setSelectedNodeByue4Id(this.selectedNodeByue4Id);
    // }
  },
  props: {
    ue4Viewer: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  computed: {
    //文件列表
    imgList() {
      return this.attrDatas
        .filter((x) => x.type === this.attrType.img)
        .map((x) => x.bimValue);
    },
  },
};
</script>
import 'ant-design-vue/dist/antd.less';
<style lang="less" scoped>
.mc-left {
  width: 400px;
  display: flex;
  flex-direction: column;
  margin-left: 20px;
  margin-top: 10px;
  height: calc(100% - 20px);
  visibility: visible;

  .BlockTitle {
    height: 46px;
    background-image: url(../../assets/svg/BlockBg.svg);
    background-position: top center;
    background-repeat: no-repeat;
    background-size: cover;

    h3 {
      color: #fff;
      margin: 0;
      padding-left: 40px;
      padding-top: 8px;
      font-weight: normal;
      text-align: left;
    }
  }

  .BlockBody {
    flex: 1;
    padding: 10px 20px;
    padding-right: 15px;
    color: #fff;
    background-image: url(../../assets/svg/BlockBg.svg);
    background-position: bottom center;
    background-repeat: no-repeat;
    background-size: cover;
    height: calc(100% - 46px);
    text-align: left;

    .tree-content {
      overflow-y: auto;
      height: 100%;
      height: calc(100% - 10px);

      .ant-tree {
        margin-left: 10px;
        font-size: 16px;
      }
    }
  }
}

.mc-right {
  // height: 268px;
  width: 314px;
  position: absolute;
  top: 12px;
  right: 30px;
  visibility: visible;

  .title {
    background-image: url(../../assets/svg/diaBg05.svg);
    background-position: top center;
    background-repeat: no-repeat;
    background-size: cover;
    height: 50px;
    line-height: 50px;
    font-size: 18px;
    padding-top: 10px;
  }

  .body {
    background-image: url(../../assets/svg/diaBg05.svg);
    background-position: bottom center;
    background-repeat: no-repeat;
    background-size: cover;
    // padding: 10px 20px;

    padding-top: 10px;
    // height: calc(100% - 80px);

    .attr-content {
      height: 100%;
      min-height: 180px;
      overflow-y: auto;
      margin: 0px 25px 10px 10px;

      .attr-row {
        min-height: 30px;
        line-height: 30px;
        overflow: hidden;
        text-align: left;
        margin-bottom: 0px;
        padding: 0px 20px 0px 30px;

        .name {
          font-size: 16px;
        }
        .content {
          font-size: 16px;
          display: inline-block;
        }
        .image {
          width: 60px;
          height: 60px;
          cursor: pointer;
        }

        .file {
          color: #1ff8e6;
          text-decoration: underline;
        }
      }

      .image-row {
        height: 70px;
      }
    }
  }
}
</style>